﻿#pragma once

#include "../MirControls/MirScene.h"
#include "../MirControls/MirAnimatedControl.h"
#include "../MirControls/MirLabel.h"
#include "../MirControls/MirMessageBox.h"
#include "../MirControls/MirImageControl.h"
#include "../../Shared/Packet.h"
#include "../../Shared/ServerPackets.h"
#include "../MirControls/MirButton.h"
#include "../MirControls/MirTextBox.h"
#include <string>
#include <vector>
#include <cmath>
#include <stdexcept>
#include <any>
#include "../../stringhelper.h"

//C# TO C++ CONVERTER NOTE: Forward class declarations:
namespace Client::MirScenes { class LoginDialog; }
namespace Client::MirScenes { class NewAccountDialog; }
namespace Client::MirScenes { class ChangePasswordDialog; }
namespace Client::MirScenes { class InputKeyDialog; }

using namespace Client::MirControls;
using namespace Client::MirGraphics;
using namespace Client::MirNetwork;
using namespace Client::MirSounds;
namespace S = ServerPackets;
namespace C = ClientPackets;

namespace Client::MirScenes
{
    class LoginScene final : public MirScene
    {
    private:
        MirAnimatedControl *_background;
    public:
        MirLabel *Version;

    private:
        LoginDialog *_login;
        NewAccountDialog *_account;
        ChangePasswordDialog *_password;

        MirMessageBox *_connectBox;

        InputKeyDialog *_ViewKey;

    public:
        MirImageControl *TestLabel, *ViolenceLabel, *MinorLabel, *YouthLabel;

        virtual ~LoginScene()
        {
            delete _background;
            delete Version;
            delete _login;
            delete _account;
            delete _password;
            delete _connectBox;
            delete _ViewKey;
            delete TestLabel;
            delete ViolenceLabel;
            delete MinorLabel;
            delete YouthLabel;
        }

        LoginScene();

        void Process() override;
        void ProcessPacket(Packet *p) override;

    private:
        void SendVersion();
        void ClientVersion(S::ClientVersion *p);
        void NewAccount(S::NewAccount *p);
        void ChangePassword(S::ChangePassword *p);
        void ChangePassword(S::ChangePasswordBanned *p);
        void Login(S::Login *p);
        void Login(S::LoginBanned *p);
        void Login(S::LoginSuccess *p);

    public:
        class LoginDialog final : public MirImageControl
        {
        public:
            MirImageControl *TitleLabel, *AccountIDLabel, *PassLabel;
            MirButton *AccountButton, *CloseButton, *OKButton, *PassButton, *ViewKeyButton;
            MirTextBox *AccountIDTextBox, *PasswordTextBox;
        private:
            bool _accountIDValid = false, _passwordValid = false;

        public:
            virtual ~LoginDialog()
            {
                delete TitleLabel;
                delete AccountIDLabel;
                delete PassLabel;
                delete AccountButton;
                delete CloseButton;
                delete OKButton;
                delete PassButton;
                delete ViewKeyButton;
                delete AccountIDTextBox;
                delete PasswordTextBox;
            }

            LoginDialog();

        private:
            void AccountIDTextBox_TextChanged(std::any sender, EventArgs *e);
            void PasswordTextBox_TextChanged(std::any sender, EventArgs *e);
        public:
            void TextBox_KeyPress(std::any sender, KeyPressEventArgs *e);
        private:
            void RefreshLoginButton();

            void Login();

        public:
            void Show() override;
            void Clear();

            #pragma region Disposable

        protected:
            void Dispose(bool disposing) override;

            #pragma endregion
        };

    public:
        class InputKeyDialog final : public MirImageControl
        {
        public:
            MirButton *const KeyEscButton, *const KeyDelButton, *const KeyRandButton, *const KeyEnterButton;

        private:
            LoginDialog *_loginDialog;

            std::vector<MirButton*> _buttons = std::vector<MirButton*>();

            std::vector<char> _letters = std::vector<char>((std::string("ABCDEFGHIJKLMNOPQRSTUVWXYZ")).begin(), (std::string("ABCDEFGHIJKLMNOPQRSTUVWXYZ")).end());
            std::vector<char> _numbers = std::vector<char>((std::string("0123456789")).begin(), (std::string("0123456789")).end());

        public:
            virtual ~InputKeyDialog()
            {
                delete KeyEscButton;
                delete KeyDelButton;
                delete KeyRandButton;
                delete KeyEnterButton;
                delete _loginDialog;
            }

            InputKeyDialog(LoginDialog *loginDialog);

        private:
            void DisposeKeys();

            void UpdateKeys();

            void SecureKeyPress(char chr);

            void SecureKeyDelete();

            MirTextBox *GetFocussedTextBox();

            #pragma region Disposable
        protected:
            void Dispose(bool disposing) override;
            #pragma endregion
        };

    public:
        class NewAccountDialog final : public MirImageControl
        {
        public:
            MirButton *OKButton, *CancelButton;

            MirTextBox *AccountIDTextBox, *Password1TextBox, *Password2TextBox, *EMailTextBox, *UserNameTextBox, *BirthDateTextBox, *QuestionTextBox, *AnswerTextBox;

            MirLabel *Description;

        private:
            bool _accountIDValid = false, _password1Valid = false, _password2Valid = false, _eMailValid = true, _userNameValid = true, _birthDateValid = true, _questionValid = true, _answerValid = true;


        public:
            virtual ~NewAccountDialog()
            {
                delete OKButton;
                delete CancelButton;
                delete AccountIDTextBox;
                delete Password1TextBox;
                delete Password2TextBox;
                delete EMailTextBox;
                delete UserNameTextBox;
                delete BirthDateTextBox;
                delete QuestionTextBox;
                delete AnswerTextBox;
                delete Description;
            }

            NewAccountDialog();


        private:
            void AccountIDTextBox_TextChanged(std::any sender, EventArgs *e);
            void Password1TextBox_TextChanged(std::any sender, EventArgs *e);
            void Password2TextBox_TextChanged(std::any sender, EventArgs *e);
            void EMailTextBox_TextChanged(std::any sender, EventArgs *e);
            void UserNameTextBox_TextChanged(std::any sender, EventArgs *e);
            void BirthDateTextBox_TextChanged(std::any sender, EventArgs *e);
            void QuestionTextBox_TextChanged(std::any sender, EventArgs *e);
            void AnswerTextBox_TextChanged(std::any sender, EventArgs *e);

            void AccountIDTextBox_GotFocus(std::any sender, EventArgs *e);
            void PasswordTextBox_GotFocus(std::any sender, EventArgs *e);
            void EMailTextBox_GotFocus(std::any sender, EventArgs *e);
            void UserNameTextBox_GotFocus(std::any sender, EventArgs *e);
            void BirthDateTextBox_GotFocus(std::any sender, EventArgs *e);
            void QuestionTextBox_GotFocus(std::any sender, EventArgs *e);
            void AnswerTextBox_GotFocus(std::any sender, EventArgs *e);

            void RefreshConfirmButton();
            void CreateAccount();

        public:
            void Show() override;

            #pragma region Disposable
        protected:
            void Dispose(bool disposing) override;
            #pragma endregion
        };

    public:
        class ChangePasswordDialog final : public MirImageControl
        {
        public:
            MirButton *const OKButton, *const CancelButton;

            MirTextBox *const AccountIDTextBox, *const CurrentPasswordTextBox, *const NewPassword1TextBox, *const NewPassword2TextBox;

        private:
            bool _accountIDValid = false, _currentPasswordValid = false, _newPassword1Valid = false, _newPassword2Valid = false;

        public:
            virtual ~ChangePasswordDialog()
            {
                delete OKButton;
                delete CancelButton;
                delete AccountIDTextBox;
                delete CurrentPasswordTextBox;
                delete NewPassword1TextBox;
                delete NewPassword2TextBox;
            }

            ChangePasswordDialog();

        private:
            void RefreshConfirmButton();

            void AccountIDTextBox_TextChanged(std::any sender, EventArgs *e);
            void CurrentPasswordTextBox_TextChanged(std::any sender, EventArgs *e);
            void NewPassword1TextBox_TextChanged(std::any sender, EventArgs *e);
            void NewPassword2TextBox_TextChanged(std::any sender, EventArgs *e);

            void ChangePassword();

        public:
            void Show() override;
        };

        #pragma region Disposable
    protected:
        void Dispose(bool disposing) override;
        #pragma endregion
    };
}
